package main

import "fmt"

func main() {
	/*
		1.概述：
			fmt包 实现了类似于 C语言 的 printf 和 scanf 的格式化 I/O。格式化动作（verb）源自 C语言 但更简单。

		2.Printing格式化
		（1）通用格式
				%v		值的 默认格式 表示
				%+v		类似 %v，但是输出 结构体 时，会添加 字段名
				%#v		值的类型的 Go语法 表示
				%%		百分号
			注：
				c := []int{1, 2, 3, 4}
				 %v 打印的是 [1,2,3,4]
				%#v 打印的的是 []int{1,2,3,4}
			所以，为了便于查看值类型，建议使用 %#v

		（2）布尔表达式
				%t		单词 true 或 false

		（3）整数格式
				%b		表示为 二进制
				%c		该值对应的 Unicode码值
				%d		表示为 十进制
				%o		表示为 八进制
				%q		该值对应的单引号括起来的 Go语法 字符字面值，必要时会采用安全的转义表示
				%x		表示为 十六进制，使用 a ~ f
				%X		表示为 十六进制，使用 A ~ F
				%U		表示为 Unicode格式：U+1234，等价于 "U+%04X"

				没有%u。整数如果是无符号类型自然输出也是无符号的。

		（4）浮点数与复数格式
				%b		无小数部分、二进制指数 的科学计数法，如 -123456p-78;
				%e		科学计数法，如 -1234.456e+78
				%E		科学计数法，如 -1234.456E+78
				%f		有小数部分，但无指数部分，如 123.456
				%F		等价于 %F
				%g		跟据实际情况采用 %e 或 %f 格式（以获得更简洁、准确的输出）
				%G		跟据实际情况采用 %E 或 %F 格式（以获得更简洁、准确的输出）

		（5）字符串和 []byte 格式
				%s		直接输出字符串 或 []byte
				%q		该值对应的双括号括起来的 Go语法 字符串字面量，必要时会采用安全的转义表示
				%x		每个字节用两字符十六进制数表示（使用 a ~ f）
				%X		每个字节用两字符十六进制数表示（使用 A ~ F）

		（6）指针格式
				%p 		表示为 十六进制，并加上前导的 0x

		（7）宽度精度格式
			宽度通过一个紧跟在百分号后面的十进制数指定，如果未指定宽度，则表示值时除必需之外不作填充。精度通过（可选的）宽度后面+点号+十进制数指定
				如果未指定精度，会用默认精度
				如果点号后没有跟数字，表示精度为0
				%f		默认宽度，默认精度
				%9f		宽度 9，默认精度
				%0.2f	默认宽度，精度 2
				%9.2f	宽度 9，精度 2
				%9.f	宽度 9，精度 0
                
        补充：  %w  专门用于包装错误，允许更复杂的错误处理和检查机制（只能用于 fmt.Errorf()函数中）

	*/
	//Printing 格式化
	//1.通用格式
	a := 10
	s := "hello world"
	p := Person{Name: "喜羊羊", Age: 18}
	c := []int{1, 2, 3, 4}

	fmt.Printf("p %%v is %v\n", p)   //p %v is {喜羊羊 18}
	fmt.Printf("p %%+v is %+v\n", p) //p %+v is {Name:喜羊羊 Age:18}
	fmt.Printf("p %%#v is %#v\n", p) //p %#v is main.Person{Name:"喜羊羊", Age:18}
	fmt.Printf("p type is %T\n", p)  //p type is main.Person

	fmt.Printf("a %%#v is %#v, a type is %T\n", a, a) //a %#v is 10, a type is int
	fmt.Printf("s %%#v is %#v, s type is %T\n", s, s) //s %#v is "hello world", s type is string
	fmt.Printf("c %%v is %v, c type is %T\n", c, c)   //c %v is [1 2 3 4], c type is []int
	fmt.Printf("c %%#v is %#v, c type is %T\n", c, c) //c %#v is []int{1, 2, 3, 4}, c type is []int
	/*结果：
	p %v is {喜羊羊 18}
	p %+v is {Name:喜羊羊 Age:18}
	p %#v is main.Person{Name:"喜羊羊", Age:18}
	p type is main.Person
	a %#v is 10, a type is int
	s %#v is "hello world", s type is string
	c %v is [1 2 3 4], c type is []int
	c %#v is []int{1, 2, 3, 4}, c type is []int
	*/

	fmt.Println("------------------------------------")

	//2.布尔表达式
	var b1 bool //默认值为 false
	fmt.Printf("b1 %%v is %v, %%#v is %#v, %%T is %T\n", b1, b1, b1)
	fmt.Printf("b1 %%t is %t, %%T is %T\n", b1, b1)

	b2 := true

	fmt.Printf("b2 %%v is %v, %%#v is %#v, %%T is %T\n", b2, b2, b2)
	fmt.Printf("b2 %%t is %t, %%T is %T\n", b2, b2)
	/*结果：
	b1 %v is false, %#v is false, %T is bool
	b1 %t is false, %T is bool
	b2 %v is true, %#v is true, %T is bool
	b2 %t is true, %T is bool
	*/

	fmt.Println("--------------------------------------------")

	//3.整数格式
	var i, j int = 15, 45
	fmt.Printf("i %%#v is %#v\tj %%#v is %#v\n", i, j)
	fmt.Printf("i %%b is %b\tj %%b is %b\n", i, j)
	fmt.Printf("i %%c is %c\tj %%c is %c\n", i, j)
	fmt.Printf("i %%d is %d\tj %%d is %d\n", i, j)
	fmt.Printf("i %%o is %o\tj %%o is %o\n", i, j)
	fmt.Printf("i %%q is %q\tj %%q is %q\n", i, j)
	fmt.Printf("i %%x is %x\tj %%x is %x\n", i, j)
	fmt.Printf("i %%X is %X\tj %%X is %X\n", i, j)
	fmt.Printf("i %%U is %U\tj %%U is %U\n", i, j)
	/*结果：
	i %#v is 15     j %#v is 45
	i %b is 1111    j %b is 101101
	i %c is         j %c is -
	i %d is 15      j %d is 45
	i %o is 17      j %o is 55
	i %q is '\x0f'  j %q is '-'
	i %x is f       j %x is 2d
	i %X is F       j %X is 2D
	i %U is U+000F  j %U is U+002D
	*/

	fmt.Println("---------------------------------------------")

	//4.浮点数与复数格式
	var x float32 = 112233445566778899
	fmt.Printf("x %%#v is %#v, %%T is %T\n", x, x)
	fmt.Printf("x %%b is %b\n", x)
	fmt.Printf("x %%e is %e\n", x)
	fmt.Printf("x %%E is %E\n", x)
	fmt.Printf("x %%f is %f\n", x)
	fmt.Printf("x %%F is %F\n", x)
	fmt.Printf("x %%g is %g\n", x)
	fmt.Printf("x %%G is %G\n", x)
	/*结果：
	x %#v is 1.1223345e+17, %T is float32
	x %b is 13065693p+33
	x %e is 1.122334e+17
	x %E is 1.122334E+17
	x %f is 112233448269152256.000000
	x %F is 112233448269152256.000000
	x %g is 1.1223345e+17
	x %G is 1.1223345E+17
	*/

	fmt.Println("---------------------------------------------------")

	a0 := "hello"
	b0 := []byte(a0)
	c0 := "你好"
	fmt.Printf("a0 %%s is %s, %%T is %T\n", a0, a0)
	fmt.Printf("b0 %%s is %s, %%T is %T\n", b0, b0)
	fmt.Printf("c0 %%s is %s, %%T is %T\n", c0, c0)
	fmt.Printf("b0 %%q is %q\n", b0)
	fmt.Printf("b0 %%x is %x\n", b0)
	fmt.Printf("c0 %%x is %x\n", c0)
	fmt.Printf("c0 %%X is %X\n", c0)
	/*结果：
	a0 %s is hello, %T is string
	b0 %s is hello, %T is []uint8
	c0 %s is 你好, %T is string
	b0 %q is "hello"
	b0 %x is 68656c6c6f
	c0 %x is e4bda0e5a5bd
	c0 %X is E4BDA0E5A5BD
	*/

	fmt.Println("--------------------------------------------")

	s0 := []int{1, 2, 3, 4}
	p0 := &s0
	fmt.Printf("*p0 is %#v\n", *p0)
	fmt.Printf("p0 %%p is %p\n", p0)
	/*结果：
	*p0 is []int{1, 2, 3, 4}
	p0 %p is 0xc000008198
	*/

	fmt.Println("-------------------------------------")

	//宽度精度格式

	fmt.Printf("PI %%f is %f\n", PI)
	fmt.Printf("PI %%f is %9f\n", PI)
	fmt.Printf("PI %%f is %.3f\n", PI)
	fmt.Printf("PI %%f is %9.3f\n", PI)
	fmt.Printf("PI %%f is %9.f\n", PI)
	/*结果：
	PI %f is 3.141593
	PI %f is  3.141593
	PI %f is 3.142
	PI %f is     3.142
	PI %f is         3
	*/

}

const PI float32 = 3.14159265358979323846

type Person struct {
	Name string
	Age  int
}
